home *** CD-ROM | disk | FTP | other *** search
- {
- PCX-bitmap 2D rotation+zoom
- a wonderful shit by Maple Leaf, 22 Oct 1996
- no fuckin rights reserved.
- -------------------------------------------------------------------------
- ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! WARNING ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
- THIS program does not work ! It was made only to show the big wonderful
- and crappy possibilities that TP/BP x.xx offers in using the 386 asm. >:(
- What the hack, man, didn't they think about "implementing" the 386 instruc-
- tions set into Pascal's ASM ?
- See version ROTIMG3.PAS+ROTASM.ASM for an example which REALLY WORKS !
- -------------------------------------------------------------------------
-
- a s s e m b l e r r u l e s ! ! ! !
- }
-
- uses alloc, bitmap, crt;
-
- var pal : array [byte] of record r,g,b:byte end;
- Img : pointer;
- Vscr, OffsVscr: word;
-
- CosTab, SinTab : array [byte] of longint;
- RowOffs : array [0..199] of word;
-
- procedure LoadImage;
- begin
- if paramcount=0 then begin
- writeln('ROTIMG ImageName.PCX');
- halt
- end;
- img:=LoadPCX(paramstr(1), @pal); { suppose no errors ! }
- end;
-
- procedure InitVideo;near;assembler;
- asm
- mov ax,13h
- int 10h { init video mode }
- mov dx,3c8h
- mov al,0
- out dx,al
- inc dx
- mov cx,768
- mov si,offset pal
- rep outsb { set palette }
- end;
-
- procedure vWait;near;assembler;
- asm
- mov dx,3DAh
- @1: in al,dx
- test al,8
- jnz @1
- @2: in al,dx
- test al,8
- jz @2
- end;
-
- procedure ShowVScreen;near;assembler;
- asm
- push ds
- push es
- mov cx,16000
- mov ax,0A000h
- mov es,ax
- mov di,0
- mov si,di
- mov ds,VScr
- cld
- db 66h; rep movsw
- pop es
- pop ds
- end;
-
-
- VAR _Ax_, _Ay_ : LongInt;
- _Bx_, _By_ : LongInt;
- _Cx_, _Cy_ : LongInt;
- WW, WH : LongInt;
- Angle : Byte; { 256-degrees system }
-
- _lx_, _Ly_:longint;
- _sx_, _Sy_:longint;
-
- HAdvX, HAdvY, VAdvX, VAdvY : longint;
-
- procedure ComputeFramePara;
- { suppose _Ax_, _Ay_, Angle, WW and WH are initialized }
- begin
-
- _Bx_:=_Ax_+trunc(WH*costab[Angle]) div 256;
- _By_:=_Ay_-trunc(WH*sintab[Angle]) div 256;
-
- _Cx_:=_Ax_+trunc(WW*costab[byte(Angle+64 {90 deg})]) div 256;
- _Cy_:=_Ay_-trunc(WW*sintab[byte(Angle+64 {90 deg})]) div 256;
-
- HAdvX:=((_Cx_-_Ax_) shl 16) div 320;
- HAdvY:=((_Cy_-_Ay_) shl 16) div 320;
- VAdvX:=((_Bx_-_Ax_) shl 16) div 200;
- VAdvY:=((_By_-_Ay_) shl 16) div 200;
- end;
-
- procedure GenHoriz;near;assembler;
- asm
- push cx
- {_sx_:=_Lx_; _Sy_:=_Ly_;}
- db 66h; mov ax,word ptr _Lx_
- db 66h; mov bx,word ptr _Ly_
- {for k:=0 to 319 do begin}
- mov cx,320
- @Loop2:
- {offsSource:=320*trunc(_Sy_)+trunc(_sx_);}
- db 66h; mov si,bx
- db 66h; ror si,15
- and si,0FFFEh
- db 66h; mov dx,ax
- db 66h; ror dx,16
- mov si,word ptr RowOffs[si]
- add si,dx
- {mem[VScr:offsVscr]:=mem[seg(img^):offsSource];
- inc(OffsVscr);}
- db 64h,8ah,04h { mov al,fs:[si] }
- mov es:[di],al
- inc di
- {_sx_:=_sx_+HAdvX;}
- db 66h; add ax,word ptr HAdvX
- {_Sy_:=_Sy_+HAdvY;}
- db 66h; add bx,word ptr HAdvY
- {if _sx_>319 then _sx_:=_sx_-320;}
- db 66h; cmp ax,0; dw 13fh {13F0000h}
- db 66h; jle @e5
- db 66h; sub ax,0; dw 140h {1400000h}
- @e5:{if _sx_<0 then _sx_:=320+_sx_;}
- db 66h; cmp ax,0h; dw 0
- db 66h; jge @e6
- db 66h; add ax,0; dw 140h {1400000h}
- @e6:{if _Sy_>199 then _Sy_:=0;}
- db 66h; cmp bx,0; dw 0C7h {0C70000h}
- db 66h; jle @e7
- db 66h; sub bx,0; dw 0C8h {0C80000h}
- @e7:{if _Sy_<0 then _Sy_:=199;}
- db 66h; cmp bx,0h; dw 0
- db 66h; jge @e8
- db 66h; add bx,0; dw 0C8h {0C80000h}
- @e8:{end;}
- dec cx
- jnz @Loop2
- pop cx
- end;
-
- procedure GenVert;near;assembler;
- asm
- push es
- db 0fh,0a0h {push fs}
- mov es,vScr
- db 8eh,26h;dw 2+offset Img {mov fs,Img[2]}
- { OffsVscr:=0; }
- mov di,0
- { _lx_:=_Ax_ shl 16; }
- db 66h; mov ax,word ptr _Ax_
- db 66h; shl ax,16
- db 66h; mov word ptr _lx_,ax
- {_Ly_:=_Ay_ shl 16;}
- db 66h; mov ax,word ptr _Ay_
- db 66h; shl ax,16
- db 66h; mov word ptr _Ly_,ax
- {for k:=0 to 199 do begin}
- mov cx,200
- @Loop1:
- { GenHoriz(trunc(_lx_),trunc(_Ly_)); }
- call GenHoriz
- {_lx_:=_lx_+VAdvX; }
- db 66h; mov ax,word ptr _lx_
- db 66h; add ax,word ptr VAdvX
- {_Ly_:=_Ly_+VAdvY; }
- db 66h; mov bx,word ptr _Ly_
- db 66h; add bx,word ptr VAdvY
- {if _lx_>319 then _lx_:=0;}
- db 66h; cmp ax,0; dw 13Fh {13F0000h}
- db 66h; jle @e1
- db 66h; sub ax,0; dw 140h {1400000h}
- @e1:{if _lx_<0 then _lx_:=319;}
- db 66h; cmp ax,0; dw 0
- db 66h; jge @e2
- db 66h; add ax,0; dw 140h {1400000h}
- @e2:{if _Ly_>199 then _Ly_:=0;}
- db 66h; cmp bx,0; dw 0C7h {0C70000h}
- db 66h; jle @e3
- db 66h; sub bx,0; dw 0C8h {0C80000h}
- @e3:{if _Ly_<0 then _Ly_:=199;}
- db 66h; cmp bx,0; dw 0
- db 66h; jge @e4
- db 66h; add bx,0; dw 0C8h {0C80000h}
- @e4:
- db 66h; mov word ptr _LX_,ax
- db 66h; mov word ptr _LY_,bx
- {end;}
- dec cx
- jnz @Loop1
- db 0fh,0a1h {pop fs}
- pop es
- end;
-
- procedure DoIt;
- begin
-
- WW:=320; WH:=200;
- _Ax_:=0; _Ay_:=0;
- Angle:=191; { approx 270 degrees in a 360-deg system }
-
- repeat
-
- { modify _Ax_, _Ay_, Angle, WW and WH ...}
- {...}
-
- inc(Angle,2);
-
- inc(_Ax_,10);
- dec(_Ay_,6);
-
- if _ax_>319 then _ax_:=_ax_-320;
- if _ax_<0 then _ax_:=_ax_+320;
- if _Ay_>199 then _Ay_:=_Ay_-200;
- if _Ay_<0 then _Ay_:=199+_Ay_;
-
- ww:=640; wh:=400;
-
- ComputeFramePara;
- GenVert;
- vWait;
- ShowVScreen;
- until keypressed;
-
- end;
-
- var k:word;
-
- begin
- LoadImage;
- Vscr:=halloc(64016);
- if (vscr=0) or (img=nil) then begin
- writeln('Allocation error.');
- hfree(vscr); free(img);
- halt
- end;
- fillchar(mem[vscr:0],64000,0);
- InitVideo;
-
- { precalculations }
- for k:=0 to 255 do begin
- SinTab[k]:=trunc(256*sin(2*pi*k/255));
- CosTab[k]:=trunc(256*cos(2*pi*k/255));
- end;
-
- for k:=0 to 199 do RowOffs[k]:=k*320;
-
- DoIt;
-
- TextMode(C80);
- free(img);
- hfree(Vscr);
- end.
-